//@author A0105543N
#include "BudgetPlanner.h"
#include <map>

using namespace std;

BudgetPlanner::BudgetPlanner():numOfItem(0), maximum(0){};
             
void BudgetPlanner::work_Budget()
{
	int i;
	cout << "How many items?\n";
	cin >> numOfItem;

	for (i = 0; i < numOfItem; i ++){
		BudgetItem* ite;
		cout << "Item " << i+1 << endl;
		ite = new BudgetItem();
		if (!ite -> record()) return;
		ItemList.push_back(ite);
	}

	cout << "What's your budget?\n";
	cin >> budget;
	map <string, int> categoryMap;
	vector<BudgetItem* > emptyList;
	work(emptyList, budget, 0, 0, categoryMap);
	print();
}
void BudgetPlanner::work(vector<BudgetItem*> choose,double remainp,int necessity,int currentItem, map<string,int> categoryMap)
{
    if (currentItem == numOfItem) return;
    if (remainp<0) return;
    
	work(choose,remainp,necessity,currentItem+1,categoryMap);//does not choose item[currentItem]
    
	if (!categoryMap.count(ItemList[currentItem] -> getCategory()) && remainp - ItemList[currentItem] -> getPrice()>= 0){
		categoryMap[ItemList[currentItem] -> getCategory()] = currentItem;
        choose.push_back(ItemList[currentItem]);
        remainp -= ItemList[currentItem]->getPrice();
        necessity += ItemList[currentItem]-> getNecessity();
    
		if (necessity == maximum) {
			solution.push_back(choose);
			spent.push_back(budget - remainp);
	}

	if (necessity > maximum){
		maximum = necessity;
		solution.clear();
		solution.push_back(choose);
		spent.clear();
		spent.push_back(budget - remainp);
	}
	work(choose,remainp,necessity,currentItem+1,categoryMap);// choose item[currentItem]
	}
}
void BudgetPlanner::print()
{
	vector< vector< BudgetItem* > >::iterator iteV;
    vector< BudgetItem* >::iterator ite;
    BudgetItem* temp;
                  
	int i=0;
                  
	iteV=solution.begin();
                  
	while (iteV!=solution.end()){
		cout<<"\nSolution "<<++i<<':'<<endl;

        ite=iteV->begin();
                  
		while (ite!=iteV->end()){
			temp=*ite;
			temp -> print();
            ite++;
		}

		cout<<"Maximum necessity:\n"<<maximum<<endl;
		cout<<fixed<<setprecision(2);
		cout<<"Spent:\n"<<spent[i-1]<<endl;
		iteV++;
	}
}